/******************************************************************************* * Copyright (c) 2000, 2010 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.internal.corext.refactoring.reorg; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.Assert; import org.eclipse.core.resources.IResource; import org.eclipse.jdt.core.IJarEntryResource; import org.eclipse.jdt.core.IJavaElement; import org.eclipse.jdt.core.JavaCore; public class ParentChecker { private IResource[] fResources; private IJavaElement[] fJavaElements; private IJarEntryResource[] fJarResources; public ParentChecker(IResource[] resources, IJavaElement[] javaElements) { this(resources, javaElements, new IJarEntryResource[0]); } public ParentChecker(IResource[] resources, IJavaElement[] javaElements, IJarEntryResource[] jarResources) { Assert.isNotNull(resources); Assert.isNotNull(javaElements); Assert.isNotNull(jarResources); fResources= resources; fJavaElements= javaElements; fJarResources= jarResources; } public boolean haveCommonParent() { return getCommonParent() != null; } public Object getCommonParent(){ if (fJavaElements.length == 0 && fResources.length == 0 && fJarResources.length == 0) return null; if (! resourcesHaveCommonParent() || ! javaElementsHaveCommonParent() || ! jarResourcesHaveCommonParent()) return null; if (fJavaElements.length == 0 && fResources.length == 0) return getCommonJarResourceParent(); if (fJavaElements.length == 0 && fJarResources.length == 0) { IResource commonResourceParent= getCommonResourceParent(); Assert.isNotNull(commonResourceParent); IJavaElement convertedToJava= JavaCore.create(commonResourceParent); if (convertedToJava != null && convertedToJava.exists()) return convertedToJava; else return commonResourceParent; } if (fResources.length == 0 && fJarResources.length == 0) return getCommonJavaElementParent(); IJavaElement convertedToJava= null; IJavaElement commonJavaElementParent= null; Object commonJarResourcesParent= null; Object commonParent= null; if (fResources.length != 0) { IResource commonResourceParent= getCommonResourceParent(); Assert.isNotNull(commonResourceParent); convertedToJava= JavaCore.create(commonResourceParent); if (convertedToJava == null || !convertedToJava.exists()) return null; } if (fJavaElements.length != 0) { commonJavaElementParent= getCommonJavaElementParent(); Assert.isNotNull(commonJavaElementParent); if (convertedToJava != null && !commonJavaElementParent.equals(convertedToJava)) return null; } commonParent= convertedToJava == null ? commonJavaElementParent : convertedToJava; if (fJarResources.length != 0) { commonJarResourcesParent= getCommonJarResourceParent(); Assert.isNotNull(commonJarResourcesParent); if (!commonJarResourcesParent.equals(commonParent)) return null; } return commonParent; } /** * Return the common parent for the jar resources. * * @return the common parent for the jar resources * @since 3.6 */ private Object getCommonJarResourceParent() { Assert.isNotNull(fJarResources); Assert.isTrue(fJarResources.length > 0);//safe - checked before return fJarResources[0].getParent(); } private IJavaElement getCommonJavaElementParent() { Assert.isNotNull(fJavaElements); Assert.isTrue(fJavaElements.length > 0);//safe - checked before return fJavaElements[0].getParent(); } private IResource getCommonResourceParent() { Assert.isNotNull(fResources); Assert.isTrue(fResources.length > 0);//safe - checked before return fResources[0].getParent(); } private boolean javaElementsHaveCommonParent() { if (fJavaElements.length == 0) return true; IJavaElement firstParent= fJavaElements[0].getParent(); Assert.isNotNull(firstParent); //this should never happen for (int i= 1; i < fJavaElements.length; i++) { if (! firstParent.equals(fJavaElements[i].getParent())) return false; } return true; } private boolean resourcesHaveCommonParent() { if (fResources.length == 0) return true; IResource firstParent= fResources[0].getParent(); Assert.isNotNull(firstParent); for (int i= 1; i < fResources.length; i++) { if (! firstParent.equals(fResources[i].getParent())) return false; } return true; } /** * Checks whether the jar resources have the same parent. * * @return <code>true</code> if the jar resources have the same parent, <code>false</code> * otherwise * @since 3.6 */ private boolean jarResourcesHaveCommonParent() { if (fJarResources.length == 0) return true; Object firstParent= fJarResources[0].getParent(); Assert.isNotNull(firstParent); for (int i= 1; i < fJarResources.length; i++) { if (! firstParent.equals(fJarResources[i].getParent())) return false; } return true; } public IResource[] getResources(){ return fResources; } public IJavaElement[] getJavaElements(){ return fJavaElements; } public void removeElementsWithAncestorsOnList(boolean removeOnlyJavaElements) { if (! removeOnlyJavaElements){ removeResourcesDescendantsOfResources(); removeResourcesDescendantsOfJavaElements(); } removeJavaElementsDescendantsOfJavaElements(); // removeJavaElementsChildrenOfResources(); //this case is covered by removeUnconfirmedArchives } private void removeResourcesDescendantsOfJavaElements() { List subResources= new ArrayList(3); for (int i= 0; i < fResources.length; i++) { IResource subResource= fResources[i]; for (int j= 0; j < fJavaElements.length; j++) { IJavaElement superElements= fJavaElements[j]; if (isDescendantOf(subResource, superElements)) subResources.add(subResource); } } removeFromSetToDelete((IResource[]) subResources.toArray(new IResource[subResources.size()])); } private void removeJavaElementsDescendantsOfJavaElements() { List subElements= new ArrayList(3); for (int i= 0; i < fJavaElements.length; i++) { IJavaElement subElement= fJavaElements[i]; for (int j= 0; j < fJavaElements.length; j++) { IJavaElement superElement= fJavaElements[j]; if (isDescendantOf(subElement, superElement)) subElements.add(subElement); } } removeFromSetToDelete((IJavaElement[]) subElements.toArray(new IJavaElement[subElements.size()])); } private void removeResourcesDescendantsOfResources() { List subResources= new ArrayList(3); for (int i= 0; i < fResources.length; i++) { IResource subResource= fResources[i]; for (int j= 0; j < fResources.length; j++) { IResource superResource= fResources[j]; if (isDescendantOf(subResource, superResource)) subResources.add(subResource); } } removeFromSetToDelete((IResource[]) subResources.toArray(new IResource[subResources.size()])); } public static boolean isDescendantOf(IResource subResource, IJavaElement superElement) { IResource parent= subResource.getParent(); while(parent != null){ IJavaElement el= JavaCore.create(parent); if (el != null && el.exists() && el.equals(superElement)) return true; parent= parent.getParent(); } return false; } public static boolean isDescendantOf(IJavaElement subElement, IJavaElement superElement) { if (subElement.equals(superElement)) return false; IJavaElement parent= subElement.getParent(); while(parent != null){ if (parent.equals(superElement)) return true; parent= parent.getParent(); } return false; } public static boolean isDescendantOf(IResource subResource, IResource superResource) { return ! subResource.equals(superResource) && superResource.getFullPath().isPrefixOf(subResource.getFullPath()); } private void removeFromSetToDelete(IResource[] resourcesToNotDelete) { fResources= ReorgUtils.setMinus(fResources, resourcesToNotDelete); } private void removeFromSetToDelete(IJavaElement[] elementsToNotDelete) { fJavaElements= ReorgUtils.setMinus(fJavaElements, elementsToNotDelete); } }